//ShapeCont.cpp

#include "ShapeCont.h"

Shape* ShapeCont::getShape(const unsigned int index)
{
	if (isLegalIndex(index))
	{
		return m_vec[index];
	}
	else
		return NULL;
}

Shape* ShapeCont::getShape(const Point& point)
{
	unsigned int index = this->getIndexByPoint(point);

	return this->getShape(index);
}

unsigned int ShapeCont::getIndexByPoint(const Point& point)
{
	unsigned int index = 0;

	while (index < m_vec.size())
	{
		if (m_vec[index]->getXPoint() == point.getX() && 
			m_vec[index]->getYPoint() == point.getY())
			return index;
		++index;
	}
	return NULL;
}

bool ShapeCont::removeShape(const unsigned int index)
{
	if (isLegalIndex(index))
	{
		m_vec.erase(m_vec.begin() + index);
		return true;
	}
	else
		return false;
}

bool ShapeCont::removeShapeFromBack()
{
	if (m_vec.size() > 0)
	{
		m_vec.pop_back();
		return true;
	}
	else
		return false;
}

bool ShapeCont::moveShapeToBack(const unsigned index)
{
	Shape* shape = NULL;

	if (isLegalIndex(index))
	{
		shape = m_vec[index];
		m_vec.erase(m_vec.begin() + index);
		m_vec.push_back(shape);
		return true;
	}
	else
		return false;
}

bool ShapeCont::moveShapeToFront(const unsigned index)
{
	Shape* shape = NULL;

	if (isLegalIndex(index))
	{
		shape = m_vec[index];
		m_vec.erase(m_vec.begin() + index);
		m_vec.insert(m_vec.begin(), shape);
		return true;
	}
	else
		return false;
}

bool ShapeCont::moveShape(const unsigned int index, int incX, int incY)
{
	if (isLegalIndex(index))
	{
		m_vec[index]->move(incX, incY);
		return true;
	}
	else
		return false;
}

void ShapeCont::drawAll(char ch, bool isFullFill) const
{
	clrscr();
	for (unsigned int i=0; i < m_vec.size(); i++)
		m_vec[i]->draw(ch, isFullFill);
}


bool ShapeCont::drawAllWithOneSpecial(char ch, bool isFullFill, unsigned int idxSpecial, char chSpecial) const
{
	clrscr();
	if (isLegalIndex(idxSpecial))
	{
		for (unsigned int i=0; i < m_vec.size(); i++)
			if (i != idxSpecial)
				m_vec[i]->draw(ch, isFullFill);
		m_vec[idxSpecial]->draw(chSpecial, isFullFill);
		return true;
	}
	else
		return false;
}

int ShapeCont::findShapeWithPointInside(const Point& point)
{
	for (unsigned int i=0; i < m_vec.size(); i++)
		if (m_vec[i]->isPointInside(point))
			return i;
	return -1;
}

void ShapeCont::execShifts()
{
	for (unsigned int i=0; i < m_vec.size(); i++)
		m_vec[i]->execShifts();
}

void ShapeCont::execShiftsWithColiisions()
{
	unsigned int vecSize = m_vec.size();
	Shape* checkedShape = NULL;

	// Scan for collisions for every shape with all other shapes and borders
	for (unsigned int i=0; i < vecSize; i++)
	{
		checkedShape = m_vec[i];
		for (unsigned int j = i + 1; j < vecSize; j++)
		{
			checkedShape->handleCollisions(m_vec[j]);
		}
	}

	for (unsigned int i=0; i < vecSize; i++)
	{
		checkedShape = m_vec[i];
		if (checkedShape->getFlagChangeX())
			checkedShape->changeXdirection();
		if (checkedShape->getFlagChangeY())
			checkedShape->changeYdirection();
		
		checkedShape->execShifts();
		checkedShape->resetShiftFlags();
	}
}

void ShapeCont::drawAllToBuffer(char ch, bool isFullFill, bool isSplit, Screen& scr)
{
	for (unsigned int i=0; i < m_vec.size(); i++)
	{
		m_vec[i]->fixShapeNegativePoint();
		m_vec[i]->drawToBuffer(ch, isFullFill, isSplit, scr);
	}
}

void ShapeCont::resetMovementParms()
{
	for (unsigned int i=0; i < m_vec.size(); i++)
	{
		m_vec[i]->reloadOriginalPoint();
		m_vec[i]->resetBuckets();
	}
}

void ShapeCont::writeToFile(ofstream& outFile, bool isBinary) const
{
	for (unsigned int i=0; i < m_vec.size(); i++)
		m_vec[i]->writeToFile(outFile, isBinary);
}

void ShapeCont::readFromFile(ifstream& inFile, bool isBinary)
{
	char askCh = NULL;
	Rect* rectP = NULL;;
	Circle* circleP = NULL;;
	string typeShape , typeShapeSuffix;
	Point point;

	if (m_vec.size() > 0)
	{
		cout << "Loading shapes from file would delete the shape you already have in the current container." << endl;
		cout << "Are you shure that you want to continue loading? (Y/N)" << endl;
		cin >> askCh;
		if (askCh != 'y' && askCh !='Y')
			return;
	}
	while (!inFile.eof())
	{
		if (isBinary)
			inFile.read(reinterpret_cast <char *> (&typeShape), sizeof(string));
		else
		{
			inFile >> typeShape >> typeShapeSuffix;
			typeShape.append(" ");
			typeShape.append(typeShapeSuffix);
		}
		if (!inFile.eof())
		{
			if (typeShape == typeid(Rect).name())
			{
			rectP = new Rect(point, 0, 0);
			rectP->readFromFile(inFile, isBinary);
			addShapeToBack(rectP);
			}
			else if (typeShape == typeid(Circle).name())
			{
				circleP = new Circle(point, 0);
				circleP->readFromFile(inFile, isBinary);
				addShapeToBack(circleP);
			}
			typeShape = "";
			circleP = NULL;
			rectP = NULL;
		}
	}
}

ShapeCont::~ShapeCont()
{
	for (unsigned int i=0; i < m_vec.size(); i++)
		delete(m_vec[i]);
}



